﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

using Ample.DAL;
using Ample.Model;

namespace Ample.DAL.User
{
    public class BoardManager : DBBase
    {
        public static BoardManager Create()
        {
            return new BoardManager();
        }

        #region Select Methods

        public IEnumerable<BoardPosition> GetBoardPositionsByLevel(string level)
        {
            using (AmpleDataContext context = DataContext)
            {
                return BoardQueries.CompiledQuery_GetPostionsByLevel(context, level).ToList();
            }
        }

        public IEnumerable<Board> GetBoardsByOpen(bool open)
        {
            using (AmpleDataContext context = DataContext)
            {
                return BoardQueries.compiledQuery_GetBoardsByOpen(context, open).ToList();
            }
        }

        public IEnumerable<TreeBoardUser> GetTreeBoardUsersByBoardId(int boardId)
        {
            using (AmpleDataContext context = DataContext)
            {
                context.LoadOptions = BoardQueries.BoardUserOptions;
                return BoardQueries.compiledQuery_GetTreeBoardUsersByBoardId(context, boardId).ToList();
            }
        }

        public IEnumerable<BoardUser> GetChildBoardUsersByBoardUserId(int boardUserId)
        {
            using (AmpleDataContext context = DataContext)
            {
                context.LoadOptions = BoardQueries.BoardUserOptions;
                return BoardQueries.compiledQuery_GetChildBoardUsersByBoardUserId(context, boardUserId).ToList();
            }
        }

        public IEnumerable<BoardUser> GetBoardUsersByBoardId(int boardId)
        {
            using (AmpleDataContext context = DataContext)
            {
                context.LoadOptions = BoardQueries.BoardUserOptions;
                return BoardQueries.compiledQuery_GetBoardUsersByBoardId(context, boardId).ToList();
            }
        }

        public BoardUser GetBoardUserByBoardUserId(int boardUserId)
        {
            using (AmpleDataContext context = DataContext)
            {
                return BoardQueries.compiledQuery_GetBoardUserByBoardUserId(context, boardUserId).SingleOrDefault();
            }
        }

        public BoardUser GetParentBoardUserByBoardUserId(int boardUserId)
        {
            using (AmpleDataContext context = DataContext)
            {
                context.LoadOptions = BoardQueries.BoardUserOptions;
                return BoardQueries.compiledQuery_GetParentBoardUserByBoardUserId(context, boardUserId).SingleOrDefault();
            }
        }

        public IEnumerable<BoardUser> GetBoardWaitingUsersByBoardId(int boardId)
        {
            using (AmpleDataContext context = DataContext)
            {
                context.LoadOptions = BoardQueries.BoardUserOptions;
                return BoardQueries.compiledQuery_GetBoardWaitingUsersByBoardId(context, boardId).ToList();
            }
        }

        public IEnumerable<Board> GetBoards()
        {
            using (AmpleDataContext context = DataContext)
            {
                return BoardQueries.compiledQuery_GetBoards(context).ToList();
            }
        }

        public Board GetBoardsById(int boardId)
        {
            using (AmpleDataContext context = DataContext)
            {
                context.LoadOptions = BoardQueries.BoardOptions;
                return BoardQueries.compiledQuery_GetBoardsById(context, boardId).SingleOrDefault();
            }
        }

        public Board GetBoardsByCode(string code)
        {
            using (AmpleDataContext context = DataContext)
            {
                return BoardQueries.compiledQuery_GetBoardsByCode(context, code).SingleOrDefault();
            }
        }
        
        #endregion

        #region Save

        public OperationStatus UpdateStatus(Board board)
        {
            AmpleDataContext context = null;

            try
            {
                context = DataContext;

                context.Ample_Boards_Update_Status(board.BoardId, board.Status);
            }
            catch (Exception exp)
            {
                return new OperationStatus(false, exp.Message, exp);
            }
            finally
            {
                if (context != null) context.Dispose();
            }
            return new OperationStatus(true, null, null);

        }


        public OperationStatus SaveBoard(Board board)
        {
            AmpleDataContext context = null;

            try
            {
                context = DataContext;
                
                //see if the board is in the system
                Model.Board dbBoard =
                    context.Boards.Where(x => x.BoardId == board.BoardId).SingleOrDefault();
                bool isNew = false;
                if (dbBoard == null)
                {
                    dbBoard = new Model.Board();
                    isNew = true;
                }
                else
                {
                    //remove them for refresh
                    //wish there was a better way to do this but...
                    context.BoardUsers.DeleteAllOnSubmit(from bu in dbBoard.BoardUsers where bu.BoardId == board.BoardId select bu);
                }

                //add the descriptors
                foreach (BoardUser bu in board.BoardUsers)
                {
                    BoardUser dbBu = new BoardUser();
                    dbBu.BoardId = bu.BoardId;
                    dbBu.UserId = bu.UserId;
                    dbBu.OrderId = bu.OrderId;
                    dbBu.PositionCode = bu.PositionCode;
                    dbBu.StartDate = bu.StartDate;
                    dbBu.Approved = bu.Approved;

                    dbBoard.BoardUsers.Add(dbBu);
                }

                //some left/right
                dbBoard.BoardId = board.BoardId;
                dbBoard.BoardCode = board.BoardCode;
                dbBoard.BoardTypeName = board.BoardTypeName;
                dbBoard.IsOpen = board.IsOpen;
                dbBoard.StartDate = board.StartDate;
                dbBoard.Status = board.Status;
                
                if (isNew)
                    context.Boards.InsertOnSubmit(dbBoard);

                context.SubmitChanges();
            }
            catch (Exception exp)
            {
                return new OperationStatus(false, exp.Message, exp);
            }
            finally
            {
                if (context != null) context.Dispose();
            }
            return new OperationStatus(true, null, null);
            
        }

        public OperationStatus SaveBoardUser(BoardUser boardUser)
        {
            AmpleDataContext context = null;
             
            try
            {
                context = DataContext;

                //see if the board is in the system
                Model.BoardUser dbBoardUser =
                    context.BoardUsers.Where(x => x.BoardUserId == boardUser.BoardUserId).SingleOrDefault();

                bool isNew = false;
                if (dbBoardUser == null)
                {
                    dbBoardUser = new Model.BoardUser();
                    isNew = true;
                }

                //some left/right
                dbBoardUser.BoardUserId = boardUser.BoardUserId;
                dbBoardUser.PositionCode = boardUser.PositionCode;
                dbBoardUser.BoardId = boardUser.BoardId;
                dbBoardUser.OrderId = boardUser.OrderId;
                dbBoardUser.StartDate = boardUser.StartDate;
                dbBoardUser.Approved = boardUser.Approved;
                dbBoardUser.UserId = boardUser.UserId;
                dbBoardUser.ParentBoardUserId = boardUser.ParentBoardUserId;
                
                if (isNew)
                    context.BoardUsers.InsertOnSubmit(dbBoardUser);

                context.SubmitChanges();
            }
            catch (Exception exp)
            {
                return new OperationStatus(false, exp.Message, exp);
            }
            finally
            {
                if (context != null) context.Dispose();
            }

            return new OperationStatus(true, null, null);

        }

        #endregion


        #region Delete Methods

        public OperationStatus DeleteBoard(Board board)
        {
            AmpleDataContext context = null;
            try
            {
                context = DataContext;
                context.Boards.Attach(board);
                context.Boards.DeleteOnSubmit(board);

                context.SubmitChanges();
            }
            catch (Exception exp)
            {
                return new OperationStatus(false, exp.Message, exp);
            }
            return new OperationStatus(true, null, null);
        }

        public OperationStatus DeleteBoardUser(BoardUser boardUser)
        {
            AmpleDataContext context = null;
            try
            {
                context = DataContext;
                context.BoardUsers.Attach(boardUser);
                context.BoardUsers.DeleteOnSubmit(boardUser);

                context.SubmitChanges();
            }
            catch (Exception exp)
            {
                return new OperationStatus(false, exp.Message, exp);
            }
            return new OperationStatus(true, null, null);
        }

        #endregion


    }
}
